package network

import (
	"bytes"
	"encoding/binary"
)

/**
	封包格式:
	Packet = PacketHeadLength(4Bytes) + PacketDataLength(4Bytes) + PacketCode(4Bytes) + PacketHead + PacketData
	PacketHeadLength: int 封包Head数据长度字段
	PacketDataLength: int 封包Data数据长度字段
	PacketCode: int 封包协议字段
	PacketHead: bytes 封包Head数据字段
	PacketData: bytes 封包Data数据字段
 */

type Message struct {
	Code int
	Head []byte
	Data []byte
}

var head []byte

func SetHead(h string) {
	head = []byte(h)
}

func GetHead() string {
	return string(head)
}

const (
	HEAD_LENGTH = 4
	DATA_LENGTH = 4
	CODE_LENGTH = 4
)

func Packet(code int, data []byte) (b []byte) {
	b = append(b, intToBytes(len(head))...)
	b = append(b, intToBytes(len(data))...)
	b = append(b, intToBytes(code)...)
	b = append(b, head...)
	b = append(b, data...)
	return
}

func Unpack(data []byte, mc chan *Message) ([]byte) {
	length 	  := len(data)
	minLength := HEAD_LENGTH + CODE_LENGTH + DATA_LENGTH

	var i int
	for i = 0; i < length; i = i + 1 {
		if length < i + minLength {
			break
		}

		hl := bytesToInt(data[:HEAD_LENGTH])
		dl := bytesToInt(data[HEAD_LENGTH : HEAD_LENGTH + DATA_LENGTH])
		c  := bytesToInt(data[HEAD_LENGTH + DATA_LENGTH : minLength])

		if length < minLength + hl + dl {
			break
		}

		h := data[minLength : minLength + hl]
		d := data[minLength + hl : minLength + hl + dl]

		mc <- &Message{Code:c, Head:h, Data:d}

		i += minLength + hl + dl - 1
	}

	if i == length {
		return make([]byte, 0)
	}

	return data[i:]
}

func intToBytes(i int) ([]byte){
	n  := int32(i)
	bf := bytes.NewBuffer([]byte{})
	binary.Write(bf, binary.BigEndian, n)
	return bf.Bytes()
}

func bytesToInt(b []byte) (int){
	var i int32
	bf := bytes.NewBuffer(b)
	binary.Read(bf, binary.BigEndian, &i)
	return int(i)
}